/**
 * This file is Copyright © 2008 Software Craftsmen Limited. All Rights Reserved.
 */
package com.softwarecraftsmen.functors;

import org.jetbrains.annotations.NotNull;

import java.util.concurrent.Callable;

public abstract class NullaryFunctor
{
	public abstract void closure();

	@NotNull
	public final NullaryFunctor curry()
	{
		return this;
	}

	@NotNull
	public NullaryReturningFunctor<Nothing> toReturningFunctor()
	{
		return new NullaryReturningFunctor<Nothing>()
		{
			@NotNull
			public Nothing closure()
			{
				NullaryFunctor.this.closure();
				return Nothing.Nothing;
			}
		};
	}

	@NotNull
	public static final NullaryFunctor IdentityNullaryFunctor = new NullaryFunctor()
	{
		public void closure()
		{
		}
	};

	@NotNull
	public Callable<Nothing> toCallable()
	{
		return new Callable<Nothing>()
		{
			@NotNull
			public Nothing call() throws Exception
			{
				closure();
				return Nothing.Nothing;
			}
		};
	}

	@NotNull
	public static <R> NullaryFunctor fromCallable(final @NotNull Callable<R> callable)
	{
		return new NullaryFunctor()
		{
			public void closure()
			{
				try
				{
					callable.call();
				}
				catch (Exception e)
				{
					throw new RuntimeException(e);
				}
			}
		};
	}

	@NotNull
	public final Runnable toRunnable()
	{
		return new Runnable()
		{
			public void run()
			{
				closure();
			}
		};
	}

	@NotNull
	public static NullaryFunctor fromRunnable(final @NotNull Runnable runnable)
	{
		return new NullaryFunctor()
		{
			public void closure()
			{
				runnable.run();
			}
		};
	}
}
